package com.foreveross.bsl.mam.rbac.application.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import com.foreveross.bsl.common.utils.bean.BeanHelper;
import com.foreveross.bsl.common.utils.enums.OperatEnum;
import com.foreveross.bsl.mam.model.rbac.domain.Privilege;
import com.foreveross.bsl.mam.rbac.application.OperationApplication;
import com.foreveross.bsl.mam.rbac.application.PrivilegeApplication;
import com.foreveross.bsl.mam.rbac.application.RbacUserRoleApplication;
import com.foreveross.bsl.mam.rbac.application.RoleApplication;
import com.foreveross.bsl.mam.rbac.application.UserApplication;
import com.foreveross.bsl.mam.rbac.application.vo.OperationVO;
import com.foreveross.bsl.mam.rbac.application.vo.PrivilegeVO;
import com.foreveross.bsl.mam.rbac.application.vo.RoleVO;
import com.foreveross.bsl.mam.rbac.application.vo.UserVO;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

/**
 * <BR>
 * [功能详细描述]
 * 
 * @author Amberlo
 * @version [mam-application-impl , 2013-6-26]
 */
@Named("privilegeApplication")
public class PrivilegeApplicationImpl implements PrivilegeApplication {

	@Autowired
	private MongoTemplate mongoTemplate;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.system.application.DatabaseInfoApplication#saveEntity
	 * (com.foreveross.bsl.system.application.vo.DatabaseInfoVO)
	 */
	@Override
	public PrivilegeVO saveEntity(PrivilegeVO entity) {
		Privilege privilege = new Privilege();
		BeanHelper.copyProperties(privilege, entity);
		privilege.save();
		entity.setId(privilege.getId());
		return entity;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.system.application.DatabaseInfoApplication#deleteEntity
	 * (com.foreveross.bsl.system.application.vo.DatabaseInfoVO)
	 */
	@Override
	public void deleteEntity(PrivilegeVO entity) {
		Privilege Privilege = new Privilege();
		BeanHelper.copyProperties(Privilege, entity);
		Privilege.delete();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.system.application.DatabaseInfoApplication#getEntity
	 * (java.lang.String)
	 */
	@Override
	public PrivilegeVO getEntity(String id) {
		Privilege Privilege = new Privilege();
		Privilege = (Privilege) Privilege.findOne(id);
		PrivilegeVO vo = new PrivilegeVO();
		BeanHelper.copyProperties(vo, Privilege);
		return vo;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.system.application.DatabaseInfoApplication#findAll()
	 */
	@Override
	public List<PrivilegeVO> findAll() {
		Privilege Privilege = new Privilege();
		Iterable iterable = Privilege.findAll();
		if (iterable != null) {
			List<PrivilegeVO> result = new ArrayList<PrivilegeVO>();
			PrivilegeVO vo;
			for (Iterator iterator = iterable.iterator(); iterator.hasNext();) {
				Privilege obj = (Privilege) iterator.next();

				vo = new PrivilegeVO();
				BeanHelper.copyProperties(vo, obj);
				result.add(vo);
			}
			return result;
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.system.application.DatabaseInfoApplication#findByPageable
	 * (org.springframework.data.domain.Pageable)
	 */
	@Override
	public Page<PrivilegeVO> findByPageable(Pageable pageable) {
		Privilege databaseInfo = new Privilege();
		Page page = databaseInfo.findAll(pageable);
		if (page != null && page.getContent() != null) {
			List<PrivilegeVO> result = new ArrayList<PrivilegeVO>();
			PrivilegeVO vo;
			for (Iterator iterator = page.getContent().iterator(); iterator
					.hasNext();) {
				Privilege obj = (Privilege) iterator.next();

				vo = new PrivilegeVO();
				BeanHelper.copyProperties(vo, obj);
				result.add(vo);
			}
			Page<PrivilegeVO> pageVO = new PageImpl<PrivilegeVO>(result,
					pageable, page.getTotalElements());
			return pageVO;
		}
		return null;
	}

	@Override
	public PrivilegeVO updateEntity(PrivilegeVO entity) {
		Privilege databaseInfo = new Privilege();
		BeanHelper.copyProperties(databaseInfo, entity);
		databaseInfo.save();
		BeanHelper.copyProperties(entity, databaseInfo);
		return null;
	}

	@Override
	public List<PrivilegeVO> getPrivilegesByRoleID(String roleID) {
		if (roleID == null)
			System.out.println("roleID is null");
		Privilege privilege = new Privilege();
		List<Privilege> ps = privilege.findListByProperty("role_ID",
				OperatEnum.EQ, roleID);
		System.out.println("privilege is " + ps);
		if (ps == null)
			return null;
		List<PrivilegeVO> psVO = new ArrayList<PrivilegeVO>();
		for (Privilege p : ps) {
			PrivilegeVO privilegeVO = new PrivilegeVO();
			BeanHelper.copyProperties(privilegeVO, p);
			psVO.add(privilegeVO);
		}
		return psVO;
	}

	@Override
	public PrivilegeVO getPrivilegeByIDs(String roleID, String appID,
			String moduleID) {
		Privilege privilege = new Privilege();
		List<Privilege> ps = privilege.findListByProperty(new String[] {
				"role_ID", "app_ID", "module_ID" }, new OperatEnum[] {
				OperatEnum.EQ, OperatEnum.EQ, OperatEnum.EQ }, new String[] {
				roleID, appID, moduleID });
		if (ps == null)
			return null;
		if (ps.size() == 0)
			return null;
		privilege = ps.get(0);
		PrivilegeVO privilegeVO = new PrivilegeVO();
		BeanHelper.copyProperties(privilegeVO, privilege);
		return privilegeVO;
	}

	@Override
	public List<PrivilegeVO> getAppPrivilegeByRoleID(String roleID, String appID) {
		Privilege privilege = new Privilege();
		List<Privilege> ps = privilege.findListByProperty(new String[] {
				"role_ID", "app_ID" }, new OperatEnum[] { OperatEnum.EQ,
				OperatEnum.EQ }, new String[] { roleID, appID });
		if (ps == null)
			return null;
		List<PrivilegeVO> psVO = new ArrayList<PrivilegeVO>();
		for (Privilege p : ps) {
			PrivilegeVO privilegeVO = new PrivilegeVO();
			BeanHelper.copyProperties(privilegeVO, p);
			psVO.add(privilegeVO);
		}
		return psVO;
	}

	@Inject
	private OperationApplication operationApplication;
	@Inject
	private UserApplication userApplication;
	@Inject
	private RbacUserRoleApplication rbacApplication;
	@Inject
	private RoleApplication roleApplication;

	@Override
	public Map<String, List> authorize(String username, String appId) {
		// Map返回结果，形式为 "privileges": [ { "roleName": "管理员", "operation": "访问" }]
		Map<String, List> result = new HashMap<String, List>();
		UserVO user = userApplication.getUserByUserName(username);
		if (user == null)
			return null;
		// 通过用户名查所属角色
		List<RoleVO> roles = rbacApplication.getRolesByUserID(user.getId());
		if (roles == null)
			return null;
		if (roles.size() == 0)
			return null;
		for (RoleVO role : roles) {
			// 查询角色对应的权限
			List<PrivilegeVO> privileges = getAppPrivilegeByRoleID(
					role.getId(), appId);
			if (privileges != null && privileges.size() != 0) {
				// 分类装在到Map上，以Map<module_ID,List<PrivilegeVO>>分类
				for (PrivilegeVO privilege : privileges) {
					String module_ID = privilege.getModule_ID();
					List resultList = result.get(module_ID);
					if (resultList == null) {
						// 结果集中没包含该集合，增添一个
						resultList = new ArrayList();
						result.put(module_ID, resultList);
					}
					List<OperationVO> ops = operationApplication
							.getOperations(privilege.getOperation_IDs());
					resultList.add(createPrivilegeImplTemplate(role.getName(),
							ops));
				}

			}
		}
		return result;

	}

	@Override
	public List<RoleVO> rolesPriviliges(String username, String appId) {
		List<RoleVO> roles = new ArrayList<RoleVO>();
		if ("guest".equalsIgnoreCase(username)) {
			RoleVO role = roleApplication.getRoleByName("guest");
			if (role != null) {
				roles.add(role);// 默认角色
			}
		} else {
			UserVO user = userApplication.getUserByUserName(username);
			if (user != null) {
				// 通过用户名查所属角色
				roles = rbacApplication.getRolesByUserID(user.getId());
				if (roles == null) {
					return null;
				}
			}
		}
		List<PrivilegeVO> privilegeList = new ArrayList<PrivilegeVO>();
		// 遍历角色对象集合，获取操作权限
		for (RoleVO role : roles) {
			// 获取该应用对应的角色模块授权
			List<PrivilegeVO> privileges = getAppPrivilegeByRoleID(
					role.getId(), appId);
			if (privileges != null) {
				for (PrivilegeVO privilege : privileges) {
					// 获取授权操作
					List<OperationVO> ops = operationApplication
							.getOperations(privilege.getOperation_IDs());
					if (ops != null && ops.size() > 0) {
						privilege.setOperations(ops);
						privilegeList.add(privilege);
					}
				}
				role.setPrivileges(privileges);
			}

		}
		return roles;

	}

	@Override
	public List<RoleVO> findRoles(String username, String appId) {
		UserVO user = userApplication.getUserByUserName(username);
		if (user == null)
			return null;
		// 通过List<RoleVO> roles用户名查所属角色
		List<RoleVO> roles = rbacApplication.getRolesByUserID(user.getId());
		if (roles != null && roles.size() > 0) {
			return roles;

		}
		return null;

	}

	private Map<String, Object> createPrivilegeImplTemplate(String roleName,
			List<OperationVO> ops) {
		Map<String, Object> pMap = new HashMap<String, Object>();
		pMap.put("roleName", roleName);
		pMap.put("operation", ops);
		return pMap;
	}

	@Override
	public void deletePrivilegesByRoleID(String roleID) {
		Privilege privilege = new Privilege();
		privilege.deleteByProperty("role_ID", OperatEnum.EQ, roleID);
	}

	@Override
	public void deletePrivilegesByWidget(String module_ID) {
		// TODO Auto-generated method stub
		Privilege privilege = new Privilege();
		privilege.deleteByProperty("module_ID", OperatEnum.EQ, module_ID);
	}

	@Override
	public void deletePrivilegesByAppId(String app_ID) {
		// TODO Auto-generated method stub
		Privilege privilege = new Privilege();
		privilege.deleteByProperty("app_ID", OperatEnum.EQ, app_ID);
	}

	@Override
	public List<PrivilegeVO> getPrivilegesByOperId(String operId) {
		// 根据操作id查询数据库
		Query query = new Query();
		query.addCriteria(Criteria.where("operations_ID").is(operId));
		List<Privilege> privileges = mongoTemplate.find(query, Privilege.class);
		// vo转换
		List<PrivilegeVO> vos = new ArrayList<PrivilegeVO>();
		for (int i = 0; i < privileges.size(); i++) {
			PrivilegeVO vo = new PrivilegeVO();
			BeanHelper.copyProperties(vo, privileges.get(i));
			vos.add(vo);
		}
		return vos;
	}

	@Override
	public void deletePrivilegesByRoleIDs(String roleID, String appID) {
		Privilege privilege = new Privilege();
		privilege.deleteByProperty(new String[] { "role_ID", "app_ID" },
				new OperatEnum[] { OperatEnum.EQ, OperatEnum.EQ },
				new String[] { roleID, appID });
	}
}
